with Sdl_Video_H;
use Sdl_Video_H;
with Sdl_Stdinc_H;
use Sdl_Stdinc_H;
with Interfaces.C;
use Interfaces.C;
with Interfaces.C.Strings;
use Interfaces.C.Strings;
with Sdl_Rwops_H;

with Ada.Unchecked_Conversion;


package body Sdl_Video is
   function To_Int32 is
     new Ada.Unchecked_Conversion (Display_Flags, Sdl_Stdinc_H.Uint32);

   function To_Flags (
                      L : in     Display_Flags_List)
                      return Sdl_Stdinc_H.Uint32 is
      Res : Sdl_Stdinc_H.Uint32 := 0;
   begin
      for I in L'Range loop
         Res := Res or To_Int32 (L (I));
      end loop;
      return Res;
   end To_Flags;

   --------------------
   -- Set_Video_Mode --
   --------------------

   function Set_Video_Mode (
                            Width           : in     Integer;
                            Height          : in     Integer;
                            Bits_Per_Pixels : in     Integer            := 32;
                            Display_Type    : in     Display_Flags_List := (Hwsurface, Doublebuf, Fullscreen ))
                            return Sdl_Surface is
   begin
      return Sdl_Setvideomode (Int (Width), Int (Height), Int (Bits_Per_Pixels), To_Flags (Display_Type));
   end Set_Video_Mode;


   function Create_Rgb_Surface (Width           : Integer;
                                Height          : Integer;
                                Depth           : Integer;
                                Rmask           : Integer := 0;
                                Gmask           : Integer := 0;
                                Bmask           : Integer := 0;
                                Amask           : Integer := 0;
                                Display_Type    : in     Display_Flags_List := (Hwsurface, Doublebuf)) return Sdl_Surface is
   begin
      return Sdl_Creatergbsurface (To_Flags (Display_Type), Int (Width), Int (Height), Int (Depth), Unsigned (Rmask), Unsigned (Gmask), Unsigned (Bmask), Unsigned (Amask));
   end Create_Rgb_Surface;




   --------------------
   -- Set_Video_Mode --
   --------------------

   procedure Set_Video_Mode (
                             Width           : in     Integer;
                             Height          : in     Integer;
                             Bits_Per_Pixels : in     Integer            := 32;
                             Display_Type    : in     Display_Flags_List := (Hwsurface, Doublebuf)) is
      S : Sdl_Surface;
   begin
      S := Set_Video_Mode (Width, Height, Bits_Per_Pixels, Display_Type);
   end Set_Video_Mode;


   -----------------
   -- Set_Caption --
   -----------------
   procedure Set_Caption (
                          Title : in     String) is
   begin
      Sdl_Wm_Setcaption (New_String (Title), Interfaces.C.Strings.Null_Ptr);
   end Set_Caption;

   procedure Set_Icon (S : Sdl_Surface; Transparency : Natural := 0) is
      T : aliased Uint8 := Uint8 (Transparency);
   begin
      if Transparency = 0 then
         Sdl_Video_H.Sdl_Wm_Seticon (S, null);
      else
         Sdl_Video_H.Sdl_Wm_Seticon (S, T'Access);
      end if;
   end Set_Icon;



   procedure Fill_Rect (
                        S : in     Sdl_Surface;
                        R :        Integer;
                        G :        Integer;
                        B :        Integer) is
      I : Int;
   begin
      I := Sdl_Fillrect (S, null, Sdl_Maprgb (S.Format, Uint8 (R), Uint8 (G), Uint8 (B)));
   end Fill_Rect;

   procedure Fill_Rect (S : Sdl_Surface; Color : Sdl_Color) is
      I : Interfaces.C.Int;
   begin
      I := Sdl_Fillrect (S, null, Color);
   end;


   function Color (Pixel_Format : access Sdl_Pixelformat; R : in Integer; G : in Integer; B : in Integer ; A : Integer := 0) return Sdl_Color is
   begin
      return Sdl_Maprgb (Pixel_Format, Uint8 (R), Uint8 (G), Uint8 (B));
   end;

   procedure Flip (S : in Sdl_Surface) is
      I : Int;
   begin
      I := Sdl_Flip (S);
   end Flip;

   function To_Rect (X, Y : Integer; W, H : Integer := 0) return Sdl_Rect is
   begin
      return (Short (X), Short (Y), Unsigned_Short (W), Unsigned_Short (H));
   end To_Rect;

   function Get_Width (S : in Sdl_Surface) return Natural is
   begin
      return Natural (S.W);
   end Get_Width;

   function Get_Height (S : in Sdl_Surface) return Natural is
   begin
      return Natural (S.H);
   end Get_Height;

   procedure Blit_Surface (Surface : Sdl_Surface; Rect : Sdl_Rect; Destination : Sdl_Surface; Origin : Sdl_Rect) is
      I : Interfaces.C.Int;
      R : aliased Sdl_Rect := Rect;
      O : aliased Sdl_Rect := Origin;
   begin
      I := Sdl_Video_H.Sdl_Upperblit (Surface, R'Access, Destination, O'Access);
   end Blit_Surface;

   procedure Blit_Surface (Surface : Sdl_Surface; Destination : Sdl_Surface; Origin : Sdl_Rect) is
      I : Interfaces.C.Int;
      O : aliased Sdl_Rect := Origin;
   begin
      I := Sdl_Video_H.Sdl_Upperblit (Surface, null, Destination, O'Access);
   end Blit_Surface;

   function Sdl_Load_Bmp (File : String) return Sdl_Surface is
      S : Sdl_Surface;
   begin
      S := Sdl_Video_H.Sdl_Loadbmp_Rw (Sdl_Rwops_H.Sdl_Rwfromfile (New_String (File), New_String ("rb")), 1);
      return S;
   end Sdl_Load_Bmp;


end Sdl_Video;
